package com.gitee.wsl.io.source

import kotlinx.io.Buffer
import kotlinx.io.InternalIoApi
import kotlinx.io.RawSink
import kotlinx.io.RawSource
import kotlinx.io.Source

open class ForwardingSource(val source: Source):RawSource {

    @InternalIoApi
     val buffer: Buffer = source.buffer
    
    override fun close() = source.close()

    override fun readAtMostTo(sink: Buffer, byteCount: Long): Long = source.readAtMostTo(sink,byteCount)

    fun exhausted(): Boolean = source.exhausted()


    /**
     * Attempts to fill the buffer with at least [byteCount] bytes of data from the underlying source
     * and throw [EOFException] when the source is exhausted before fulfilling the requirement.
     *
     * If the buffer already contains required number of bytes then there will be no requests to
     * the underlying source.
     *
     * @param byteCount the number of bytes that the buffer should contain.
     *
     * @throws EOFException when the source is exhausted before the required bytes count could be read.
     * @throws IllegalStateException when the source is closed.
     * @throws IllegalArgumentException when [byteCount] is negative.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.require
     */
     fun require(byteCount: Long) = source.require(byteCount)

    /**
     * Attempts to fill the buffer with at least [byteCount] bytes of data from the underlying source
     * and returns a value indicating if the requirement was successfully fulfilled.
     *
     * `false` value returned by this method indicates that the underlying source was exhausted before
     * filling the buffer with [byteCount] bytes of data.
     *
     * @param byteCount the number of bytes that the buffer should contain.
     *
     * @throws IllegalArgumentException when [byteCount] is negative.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.request
     */
     fun request(byteCount: Long): Boolean= source.request(byteCount)

    /**
     * Removes a byte from this source and returns it.
     *
     * @throws EOFException when there are no more bytes to read.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.readByte
     */
     fun readByte(): Byte= source.readByte()

    /**
     * Removes two bytes from this source and returns a short integer composed of it according to the big-endian order.
     *
     * @throws EOFException when there are not enough data to read a short value.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.readShort
     */
     fun readShort(): Short = source.readShort()

    /**
     * Removes four bytes from this source and returns an integer composed of it according to the big-endian order.
     *
     * @throws EOFException when there are not enough data to read an int value.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.readInt
     */
     fun readInt(): Int = source.readInt()

    /**
     * Removes eight bytes from this source and returns a long integer composed of it according to the big-endian order.
     *
     * @throws EOFException when there are not enough data to read a long value.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.readLong
     */
     fun readLong(): Long = source.readLong()

    /**
     * Reads and discards [byteCount] bytes from this source.
     *
     * @param byteCount the number of bytes to be skipped.
     *
     * @throws EOFException when the source is exhausted before the requested number of bytes can be skipped.
     * @throws IllegalArgumentException when [byteCount] is negative.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.skip
     */
     fun skip(byteCount: Long) = source.skip(byteCount)

    /**
     * Removes up to `endIndex - startIndex` bytes from this source, copies them into [sink] subrange starting at
     * [startIndex] and ending at [endIndex], and returns the number of bytes read, or -1 if this source is exhausted.
     *
     * @param sink the array to which data will be written from this source.
     * @param startIndex the startIndex (inclusive) of the [sink] subrange to read data into, 0 by default.
     * @param endIndex the endIndex (exclusive) of the [sink] subrange to read data into, `sink.size` by default.
     *
     * @throws IndexOutOfBoundsException when [startIndex] or [endIndex] is out of range of [sink] array indices.
     * @throws IllegalArgumentException when `startIndex > endIndex`.
     * @throws IllegalStateException when the source is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.readAtMostToByteArray
     */
     fun readAtMostTo(sink: ByteArray, startIndex: Int = 0, endIndex: Int = sink.size): Int = source.readAtMostTo(sink, startIndex, endIndex)

    /**
     * Removes exactly [byteCount] bytes from this source and writes them to [sink].
     *
     * @param sink the sink to which data will be written from this source.
     * @param byteCount the number of bytes that should be written into [sink]
     *
     * @throws IllegalArgumentException when [byteCount] is negative.
     * @throws EOFException when the requested number of bytes cannot be read.
     * @throws IllegalStateException when the source or [sink] is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.readSourceToSink
     */
     fun readTo(sink: RawSink, byteCount: Long) = source.readTo(sink, byteCount)

    /**
     * Removes all bytes from this source, writes them to [sink], and returns the total number of bytes
     * written to [sink].
     *
     * Return 0 if this source is exhausted.
     *
     * @param sink the sink to which data will be written from this source.
     *
     * @throws IllegalStateException when the source or [sink] is closed.
     * @throws IOException when some I/O error occurs.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.transferTo
     */
     fun transferTo(sink: RawSink): Long = source.transferTo(sink)

    /**
     * Returns a new [Source] that can read data from this source without consuming it.
     * The returned source becomes invalid once this source is next read or closed.
     *
     * Peek could be used to lookahead and read the same data multiple times.
     *
     * @throws IllegalStateException when the source is closed.
     *
     * @sample kotlinx.io.samples.KotlinxIoCoreCommonSamples.peekSample
     */
     fun peek(): Source = source.peek()
}